<route lang="json5" type="page">
{
style: {
navigationBarTitleText: '班级管理',
},
}
</route>

<script setup lang="ts">
import { useMessage, useToast } from 'wot-design-uni'
import api from '@/api'
import { HttpError, RequestError, tryApi, UnknownException } from '@/api/effect-api'
import { useClassStore, useUserStore } from '@/store'

const userStore = useUserStore()
const classStore = useClassStore()

const messageApi = useMessage()
const transferMessageApi = useMessage('transfer-message-box')
const toastApi = useToast()

const data = reactive<{
  classInfo: Awaited<ReturnType<typeof api.classes.getClassInfoByClassId>>['data'] | null
  memberInfos: (Awaited<ReturnType<typeof api.classes.getMembersByClassId>>['data'][number] & {
    avatarLoadError?: boolean
  })[]
  prompt: {
    transferTargetId: number
  }
}>({
      classInfo: null,
      memberInfos: [],
      prompt: {
        transferTargetId: -1,
      },
    })

function handleAvatarError(index: number) {
  if (data.memberInfos[index]) {
    data.memberInfos[index].avatarLoadError = true
    console.error(`Avatar for user ${data.memberInfos[index].nickname} (index: ${index}) failed to load.`)
  }
}

onLoad(async (query) => {
  try {
    const classInfo = await tryApi(() => api.classes.getClassInfoByClassId(Number.parseInt(query.classId)))
    data.classInfo = classInfo

    const memberInfos = await tryApi(() => api.classes.getMembersByClassId(classInfo.id))
    data.memberInfos = memberInfos
      .map(item => ({
        ...item,
        avatarLoadError: !item.avatar,
      }))
      .toSorted((a, b) => {
        const currentUserId = userStore.userInfo.id

        if (`${a.userId}` === currentUserId)
          return -1
        if (`${b.userId}` === currentUserId)
          return 1

        if (a.role === 'teacher' && b.role !== 'teacher')
          return -1
        if (a.role !== 'teacher' && b.role === 'teacher')
          return 1

        return 0
      })
    data.prompt.transferTargetId = data.memberInfos.filter(({ userId }) => userStore.userInfo.id !== `${userId}`)[0]?.userId ?? -1
  }
  catch (error) {
    if (error instanceof HttpError) {
      toastApi.error({
        msg: '网络错误',
        duration: 1500,
        iconName: 'error',
      })
    }
    else if (error instanceof RequestError) {
      toastApi.error({
        msg: error.msg,
        duration: 1500,
        iconName: 'error',
      })
    }
  }
})

async function handleModify() {
  try {
    const resp = await messageApi.prompt({
      title: '编辑班级名称',
      inputPattern: /.+/,
    })

    if (typeof resp === 'object' && resp !== null && 'value' in resp && typeof resp.value === 'string') {
      await tryApi(() => api.classes.modifyClassNameAndDescByClassId(data.classInfo.id, resp.value as string, data.classInfo.description))

      data.classInfo.className = resp.value as string
      classStore.setRefresh(true)
      classStore.setInitialClassId(data.classInfo.id)
      toastApi.success({
        msg: '修改成功',
        iconName: 'success',
        duration: 1500,
      })
    }
    else {
      throw new UnknownException({ error: new Error(`预期外的数据：${resp}`) })
    }
  }
  catch (error) {
    if (error instanceof UnknownException) {
      if (!(typeof error.error === 'object' && error.error !== null && 'action' in error.error && (error.error as any).action === 'cancel')) {
        console.error(error)
      }
    }
    else if (error instanceof HttpError) {
      toastApi.error({
        msg: '网络错误',
        duration: 1500,
        iconName: 'error',
      })
    }
    else if (error instanceof RequestError) {
      toastApi.error({
        msg: error.msg,
        duration: 1500,
        iconName: 'error',
      })
    }
  }
}

async function handleTransfer() {
  try {
    await transferMessageApi.confirm({
      title: '选择转让对象',
    })

    await tryApi(() => api.classes.transferClassToMember(data.classInfo.id, data.prompt.transferTargetId))

    toastApi.success({
      msg: '转让成功',
      iconName: 'success',
      duration: 1500,
      closed: () => {
        classStore.setRefresh(true)
        classStore.setInitialClassId(data.classInfo.id)
        uni.switchTab({
          url: '/pages-sub/admin/class/index',
        })
      },
    })
  }
  catch (error) {
    if (error instanceof UnknownException) {
      // 用户取消操作，不做任何处理
    }
    else if (error instanceof HttpError) {
      toastApi.error({
        msg: '网络错误',
        duration: 1500,
        iconName: 'error',
      })
    }
    else if (error instanceof RequestError) {
      toastApi.error({
        msg: error.msg,
        duration: 1500,
        iconName: 'error',
      })
    }
  }
}

async function handleLockOn() {
  try {
    const resMsg = await tryApi(() => api.classes.lockClassByClassId(data.classInfo.id, !data.classInfo.isLocked))

    data.classInfo.isLocked = !data.classInfo.isLocked
    toastApi.success({
      msg: resMsg,
      duration: 1500,
      iconName: 'success',
    })
  }
  catch (error) {
    if (error instanceof HttpError) {
      toastApi.error({
        msg: '网络错误',
        duration: 1500,
        iconName: 'error',
      })
    }
    else if (error instanceof RequestError) {
      toastApi.error({
        msg: error.msg,
        duration: 1500,
        iconName: 'error',
      })
    }
  }
}

async function handleDelete() {
  try {
    await messageApi.confirm({
      msg: '确定要解散班级吗？',
      title: '提示',
    })

    await tryApi(() => api.classes.deleteClassByClassId(data.classInfo.id))

    toastApi.success({
      msg: '解散成功',
      iconName: 'success',
      duration: 1500,
      closed: () => {
        classStore.setRefresh(true)
        uni.switchTab({
          url: '/pages-sub/admin/class/index',
        })
      },
    })
  }
  catch (error) {
    if (error instanceof UnknownException) {
      // 用户取消操作，不做任何处理
    }
    else if (error instanceof HttpError) {
      toastApi.error({
        msg: '网络错误',
        duration: 1500,
        iconName: 'error',
      })
    }
    else if (error instanceof RequestError) {
      toastApi.error({
        msg: error.msg,
        duration: 1500,
        iconName: 'error',
      })
    }
  }
}

async function handleDeleteMember(member: Awaited<ReturnType<typeof api.classes.getMembersByClassId>>['data'][number] & {
  avatarLoadError?: boolean
}) {
  try {
    await messageApi.confirm({
      msg: `确定要移除成员${member.nickname}吗？`,
      title: '提示',
    })

    await tryApi(() => api.classes.deleteMemberFromClass(data.classInfo.id, member.userId))

    data.memberInfos = data.memberInfos.filter(({ userId }) => userId !== member.userId)
    toastApi.success({
      msg: '移除成功',
      iconName: 'success',
      duration: 1500,
    })
  }
  catch (error) {
    if (error instanceof UnknownException) {
      // 用户取消操作，不做任何处理
    }
    else if (error instanceof HttpError) {
      toastApi.error({
        msg: '网络错误',
        duration: 1500,
        iconName: 'error',
      })
    }
    else if (error instanceof RequestError) {
      toastApi.error({
        msg: error.msg,
        duration: 1500,
        iconName: 'error',
      })
    }
  }
}
</script>

<template>
  <view class="manage-class-container">
    <wd-message-box />
    <wd-message-box selector="transfer-message-box">
      <wd-picker-view
        v-model="data.prompt.transferTargetId"
        :columns="data.memberInfos.filter(({ userId }) => userStore.userInfo.id !== `${userId}`).map((info) => ({ label: info.nickname, value: info.userId, disabled: false }))"
      />
    </wd-message-box>
    <wd-card :title="data.classInfo?.className">
      <p>{{ `老师：${userStore.userInfo.nickname}` }}</p>
      <p>{{ `班级口令：${data.classInfo?.classCode}` }}</p>
      <template #footer>
        <view class="action-btn-group">
          <wd-button size="small" class="action-btn" icon="edit-outline" @click="handleModify()">
            修改
          </wd-button>
          <wd-button size="small" class="action-btn" icon="jump" :disabled="data.memberInfos.length <= 1" @click="handleTransfer()">
            转让
          </wd-button>
          <wd-button size="small" class="action-btn" icon="lock-on" @click="handleLockOn()">
            锁定
          </wd-button>
          <wd-button size="small" class="action-btn" icon="delete-thin" @click="handleDelete()">
            删除
          </wd-button>
        </view>
      </template>
    </wd-card>

    <wd-card>
      <wd-cell-group :title="`成员（${data.memberInfos.length}人）`" border>
        <wd-cell v-for="(item, index) in data.memberInfos" :key="item.userId" size="large" :title="item.nickname">
          <template #icon>
            <view class="avatar-wrapper">
              <template v-if="item.avatar && !item.avatarLoadError">
                <image
                  :src="item.avatar"
                  alt="成员头像"
                  class="member-avatar"
                  mode="aspectFill"
                  @error="handleAvatarError(index)"
                />
              </template>
              <template v-else>
                <view class="member-avatar-placeholder">
                  {{ item.nickname.at(0) }}
                </view>
              </template>
            </view>
          </template>
          <wd-icon
            v-if="`${item.userId}` !== userStore.userInfo.id" name="delete-thin"
            @click="handleDeleteMember(item)"
          />
        </wd-cell>
      </wd-cell-group>
    </wd-card>
  </view>
</template>

<style scoped>
.manage-class-container {
  padding: 15px;
  background: linear-gradient(135deg, #e0f6ff 0%, #f0fff0 50%, #fff5ee 100%);
  min-height: 100vh;
}

.action-btn-group {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  justify-content: space-between;
  align-items: center;

  @media (max-width: 480px) {
    gap: 4px;
  }
}

.action-btn {
  flex: 1;
  min-width: 60px;
  max-width: 80px;

  @media (max-width: 480px) {
    min-width: 50px;
    max-width: 70px;
  }

  @media (min-width: 768px) {
    min-width: 70px;
    max-width: 90px;
  }
}

/* 深度选择器确保样式应用到组件内部 */
:deep(.action-btn) {
  .wd-button {
    width: 100%;
    font-size: 12px;

    @media (max-width: 480px) {
      font-size: 11px;
      padding: 4px 8px;
    }

    @media (min-width: 768px) {
      font-size: 13px;
      padding: 6px 12px;
    }
  }

  .wd-button__text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* 新增的头像样式 */
.avatar-wrapper {
  width: 28px; /* 根据wd-cell icon的大小调整 */
  height: 28px; /* 根据wd-cell icon的大小调整 */
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #6a5acd; /* 默认背景色，文字头像时显示 */
  margin-right: 10px; /* 调整与标题的间距 */
  flex-shrink: 0;
}

.member-avatar {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.member-avatar-placeholder {
  font-size: 14px; /* 调整文字大小 */
  font-weight: bold;
  color: #ffffff;
}
</style>
